package com.abcode.test.springbootmybatisplus.gen.nick;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 机器人昵称生成器
 */
@Service
@Slf4j
public class RobotNicknameGenerator {

    // 中文字符集
    private static final String CHINESE_CHARACTERS = "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮卞齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄麴家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫宁仇栾暴甘钭厉戎祖武符刘景詹束龙叶幸司韶郜黎蓟薄印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阴郁胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍却璩桑桂濮牛寿通边扈燕冀郏浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东殴殳沃利蔚越夔隆师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查后荆红游竺权逯盖益桓公晋楚闫法汝鄢涂钦归海岳帅缑亢况后有琴梁丘左丘东门西门商牟佘佴伯赏南宫墨哈谯笪年爱阳佟第五言福百家姓续";

    // 英文名常用前缀
    private static final List<String> ENGLISH_PREFIXES = Arrays.asList(
            "Alex", "Ben", "Chris", "David", "Ethan", "Frank", "Grace", "Hannah", "Ivan", "Jack",
            "Kate", "Liam", "Mike", "Nora", "Olivia", "Peter", "Quinn", "Ryan", "Sarah", "Tom",
            "Uma", "Victor", "Wendy", "Xavier", "Yvonne", "Zach", "Adam", "Beth", "Carl", "Dana"
    );

    // 英文名常用后缀
    private static final List<String> ENGLISH_SUFFIXES = Arrays.asList(
            "son", "man", "woman", "er", "ess", "ling", "ton", "field", "wood", "stone",
            "heart", "light", "star", "brook", "dale", "ford", "gate", "hill", "lake", "meadow",
            "moor", "pond", "river", "stream", "vale", "wood", "bush", "thorn", "berry", "rose"
    );

    // 中文形容词列表
    private List<String> chineseAdjectives = new ArrayList<>();

    // 中文名词列表
    private List<String> chineseNouns = new ArrayList<>();

    // 已生成的昵称集合，用于去重
    private final Set<String> usedNicknames = Collections.synchronizedSet(new HashSet<>());

    // 随机数生成器
    private final Random random = ThreadLocalRandom.current();

    public RobotNicknameGenerator() {
        initChineseWordLists();
    }

    /**
     * 初始化中文词汇列表
     */
    private void initChineseWordLists() {
        try {
            // 从类路径加载形容词和名词列表
            byte[] adjectiveBytes = Files.readAllBytes(
                    Paths.get(Objects.requireNonNull(getClass().getClassLoader().getResource("chinese_adjectives.txt")).toURI())
            );
            String adjectives = new String(adjectiveBytes, StandardCharsets.UTF_8);
            chineseAdjectives = Arrays.asList(adjectives.split(","));

            byte[] nounBytes = Files.readAllBytes(
                    Paths.get(Objects.requireNonNull(getClass().getClassLoader().getResource("chinese_nouns.txt")).toURI())
            );
            String nouns = new String(nounBytes, StandardCharsets.UTF_8);
            chineseNouns = Arrays.asList(nouns.split(","));

            log.info("成功加载中文词汇：{}个形容词，{}个名词", chineseAdjectives.size(), chineseNouns.size());
        } catch (Exception e) {
            log.error("加载中文词汇列表失败，使用默认随机生成方式", e);
            // 生成备用词汇列表
            chineseAdjectives = generateDefaultChineseWords(500);
            chineseNouns = generateDefaultChineseWords(500);
        }
    }

    /**
     * 生成默认中文词汇列表
     *
     * @param count 词汇数量
     * @return 词汇列表
     */
    private List<String> generateDefaultChineseWords(int count) {
        List<String> words = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int length = random.nextInt(2) + 2; // 2-3个字符
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < length; j++) {
                sb.append(CHINESE_CHARACTERS.charAt(random.nextInt(CHINESE_CHARACTERS.length())));
            }
            words.add(sb.toString());
        }
        return words;
    }

    /**
     * 生成指定数量的机器人昵称
     *
     * @param count 昵称数量
     * @return 昵称列表
     */
    public List<String> generateNicknames(int count) {
        List<String> nicknames = new ArrayList<>();
        int chineseCount = count * 4 / 5;
        int englishCount = count - chineseCount;

        // 生成中文昵称
        for (int i = 0; i < chineseCount; i++) {
            nicknames.add(generateUniqueChineseNickname());
        }

        // 生成英文昵称
        for (int i = 0; i < englishCount; i++) {
            nicknames.add(generateUniqueEnglishNickname());
        }

        // 打乱顺序
        Collections.shuffle(nicknames, random);
        return nicknames;
    }

    /**
     * 生成唯一的中文昵称
     *
     * @return 中文昵称
     */
    private String generateUniqueChineseNickname() {
        String nickname;
        do {
            nickname = generateChineseNickname();
        } while (!usedNicknames.add(nickname));
        return nickname;
    }

    /**
     * 生成唯一的英文昵称
     *
     * @return 英文昵称
     */
    private String generateUniqueEnglishNickname() {
        String nickname;
        do {
            nickname = generateEnglishNickname();
        } while (!usedNicknames.add(nickname));
        return nickname;
    }

    /**
     * 生成中文昵称
     *
     * @return 中文昵称
     */
    private String generateChineseNickname() {
        // 70%概率使用形容词+名词组合
        if (random.nextDouble() < 0.7 && !chineseAdjectives.isEmpty() && !chineseNouns.isEmpty()) {
            String adj = chineseAdjectives.get(random.nextInt(chineseAdjectives.size()));
            String noun = chineseNouns.get(random.nextInt(chineseNouns.size()));
            String combination = adj + noun;

            // 确保长度符合要求
            if (combination.length() >= 2 && combination.length() <= 6) {
                return combination;
            }
        }

        // 30%概率随机生成或组合不满足长度要求时随机生成
        int length = random.nextInt(5) + 2; // 2-6个字符
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(CHINESE_CHARACTERS.charAt(random.nextInt(CHINESE_CHARACTERS.length())));
        }
        return sb.toString();
    }

    /**
     * 生成英文昵称
     *
     * @return 英文昵称
     */
    private String generateEnglishNickname() {
        // 80%概率使用前缀+后缀组合
        if (random.nextDouble() < 0.8) {
            String prefix = ENGLISH_PREFIXES.get(random.nextInt(ENGLISH_PREFIXES.size()));
            String suffix = ENGLISH_SUFFIXES.get(random.nextInt(ENGLISH_SUFFIXES.size()));
            String combination = prefix + suffix;

            // 确保长度符合要求
            if (combination.length() >= 4 && combination.length() <= 12) {
                return combination;
            }
        }

        // 20%概率随机生成或组合不满足长度要求时随机生成
        // 使用英文常用字符集
        String englishChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int length = random.nextInt(9) + 4; // 4-12个字符
        StringBuilder sb = new StringBuilder();

        // 确保首字母大写
        sb.append(englishChars.charAt(random.nextInt(26) + 26));

        // 生成剩余字符
        for (int i = 1; i < length; i++) {
            sb.append(englishChars.charAt(random.nextInt(26)));
        }

        return sb.toString();
    }

    /**
     * 检查昵称是否已存在
     *
     * @param nickname 昵称
     * @return 是否存在
     */
    public boolean exists(String nickname) {
        return usedNicknames.contains(nickname);
    }

    /**
     * 重置已使用的昵称集合
     */
    public void reset() {
        usedNicknames.clear();
    }
}    